"""
通用工具函数
"""
from datetime import datetime, date
from flask import flash, redirect, url_for
from functools import wraps


def flash_errors(form):
    """显示表单错误信息"""
    for field, errors in form.errors.items():
        for error in errors:
            flash(f"{getattr(form, field).label.text}: {error}", 'error')


def format_date(date_obj):
    """格式化日期"""
    if isinstance(date_obj, datetime):
        return date_obj.strftime('%Y-%m-%d %H:%M:%S')
    elif isinstance(date_obj, date):
        return date_obj.strftime('%Y-%m-%d')
    return str(date_obj) if date_obj else ""


def format_time(date_obj):
    """格式化时间"""
    if isinstance(date_obj, datetime):
        return date_obj.strftime('%H:%M:%S')
    return str(date_obj) if date_obj else ""


def format_currency(amount):
    """格式化货币"""
    try:
        return f"¥{float(amount):,.2f}"
    except (ValueError, TypeError):
        return "¥0.00"


def calculate_percentage(part, total):
    """计算百分比"""
    try:
        if total == 0:
            return 0
        return round((part / total) * 100, 2)
    except (ValueError, TypeError):
        return 0


def permission_required(permission_name):
    """权限装饰器"""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            from flask_login import current_user
            from flask import flash, redirect, url_for
            
            # 检查用户是否登录
            if not current_user.is_authenticated:
                flash('请先登录', 'error')
                return redirect(url_for('auth.login'))
            
            # 管理员拥有所有权限
            if current_user.role == 'admin':
                return f(*args, **kwargs)
            
            # 解析权限名称，格式为 "resource:action"
            # 例如: "followup:create", "followup:edit", "followup:delete"
            resource, action = permission_name.split(':')
            
            # 根据资源类型和操作类型检查权限
            if resource == 'followup':
                # 客户跟进权限检查
                if action == 'create':
                    # 所有登录用户都可以创建跟进记录
                    return f(*args, **kwargs)
                elif action in ['edit', 'delete']:
                    # 编辑和删除权限需要检查跟进记录的负责人
                    followup_id = kwargs.get('followup_id') or args[0] if args else None
                    if followup_id:
                        from app.models.customer import FollowUp
                        followup = FollowUp.query.get(followup_id)
                        if followup and followup.manager_id == current_user.id:
                            return f(*args, **kwargs)
                    
                    flash('您没有权限执行此操作', 'error')
                    return redirect(url_for('followup.list_followups'))
                elif action == 'confirm_solution':
                    # 解决方案配合确认权限
                    followup_id = kwargs.get('followup_id') or args[0] if args else None
                    if followup_id:
                        from app.models.customer import FollowUp
                        followup = FollowUp.query.get(followup_id)
                        # 只有解决方案人员本人或管理员可以确认
                        if followup and (followup.solution_support_user_id == current_user.id or 
                                        current_user.role in ['admin', 'manager']):
                            return f(*args, **kwargs)
                    
                    flash('您没有权限确认此配合请求', 'error')
                    return redirect(url_for('followup.list_followups'))
            
            # 默认拒绝访问
            flash('您没有权限执行此操作', 'error')
            return redirect(url_for('main.index'))
            
        return decorated_function
    return decorator


def get_pagination_params(request):
    """获取分页参数"""
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    
    # 限制每页显示数量
    if per_page > 100:
        per_page = 100
    elif per_page < 5:
        per_page = 5
        
    return page, per_page


def safe_get(dictionary, key, default=None):
    """安全获取字典值"""
    try:
        return dictionary.get(key, default)
    except (AttributeError, TypeError):
        return default


def truncate_string(text, length=50, suffix='...'):
    """截断字符串"""
    if not text:
        return ""
    
    if len(text) <= length:
        return text
    
    return text[:length] + suffix


def nl2br(text):
    """将换行符转换为HTML的<br>标签"""
    if not text:
        return ""
    # 将换行符替换为<br>标签
    return text.replace('\n', '<br>\n').replace('\r\n', '<br>\n')